# App包初始化文件
import traceback
import uuid
from flask import Flask, render_template, request, jsonify
from werkzeug.exceptions import HTTPException

# 导入扩展
from app.extensions import db, init_extensions

# 导入API蓝图
    from app.api import api_bp
    
    # 导入RESTful API蓝图
    from app.api.restful import api_v1_bp
    from app.api.restful.v2 import api_v2_bp  # 导入v2 API蓝图
    from app.api.docs import init_docs  # 导入文档初始化函数

def create_app(config_name='development'):
    """
    应用工厂函数
    :param config_name: 配置名称，默认为development
    :return: Flask应用实例
    """
    app = Flask(__name__)
    
    # 加载配置
    from config import config
    app.config.update(config[config_name])
    
    # 初始化扩展
    init_extensions(app)
    
    # 配置Flask-Login用户加载器
    from app.models.user import User
    from flask_login import LoginManager
    
    login_manager = LoginManager()
    login_manager.init_app(app)
    
    @login_manager.user_loader
    def load_user(user_id):
        """Flask-Login用户加载器"""
        return User.query.get(int(user_id))
    
    # 初始化Redis
    with app.app_context():
        from app.utils.redis_init import init_redis, setup_redis_defaults
        if init_redis():
            setup_redis_defaults()
    
    # 导入所有路由模块，确保它们被注册到api_bp
    from app.api.routes import index, user
    
    # 注册蓝图
    from app.api import api_bp
    
    app.register_blueprint(api_bp)
    
    # 注册RESTful API蓝图
    app.register_blueprint(api_v1_bp, url_prefix='/api/v1')
    app.register_blueprint(api_v2_bp, url_prefix='/api/v2')  # 注册v2 API蓝图
    
    # 初始化Swagger文档
    init_docs(app)
    
    # 直接注册profile蓝图到应用，不通过api_bp
    from app.api.controllers.profile_controller import profile_bp
    app.register_blueprint(profile_bp)
    
    # 注册OAuth蓝图
    from app.api.controllers.oauth_controller import oauth_bp
    app.register_blueprint(oauth_bp)
    
    # 注册认证视图蓝图
    from app.api.views.auth_views import auth_bp
    app.register_blueprint(auth_bp)
    
    # 注册管理员蓝图
    from app.api.controllers.admin_controller import admin_bp
    app.register_blueprint(admin_bp)
    
    # 注册主页面蓝图
    from app.api.views.main_views import main_bp
    app.register_blueprint(main_bp)
    
    # 注册测试蓝图（仅在开发环境）
    if app.config.get('DEBUG', False):
        from app.api.controllers.test_controller import test_bp
        app.register_blueprint(test_bp)
    
    # 导入所有模型，确保SQLAlchemy能够识别它们
    from app import models
    from app.models.uploaded_file import UploadedFile
    
    # 注册请求日志中间件
    from app.utils.logging_middleware import log_request
    app.before_request(log_request(lambda: None))  # 使用before_request记录所有请求
    
    # 注册错误处理器
    register_error_handlers(app)
    
    return app


def register_error_handlers(app):
    """
    注册错误处理函数
    """
    # 404错误处理
    @app.errorhandler(404)
    def not_found_error(error):
        # 如果是AJAX请求，返回JSON错误
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': '页面未找到'
            }), 404
        
        return render_template('errors/404.html'), 404
    
    # 500错误处理
    @app.errorhandler(500)
    def internal_error(error):
        # 记录错误信息
        error_id = str(uuid.uuid4())[:8]  # 生成简短的错误ID
        app.logger.error(f"Error ID: {error_id} - {str(error)}\n{traceback.format_exc()}")
        
        # 如果是AJAX请求，返回JSON错误
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': '服务器内部错误',
                'error_id': error_id
            }), 500
        
        return render_template('errors/500.html', error_id=error_id), 500
    
    # 403错误处理
    @app.errorhandler(403)
    def forbidden_error(error):
        # 如果是AJAX请求，返回JSON错误
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': '访问被拒绝'
            }), 403
        
        return render_template('errors/403.html'), 403
    
    # 400错误处理
    @app.errorhandler(400)
    def bad_request_error(error):
        # 如果是AJAX请求，返回JSON错误
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': '请求无效'
            }), 400
        
        return render_template('errors/error.html', 
                              error_code=400,
                              error_title='请求无效',
                              error_description='您的请求格式不正确或包含无效数据。',
                              error_icon='fa-exclamation-triangle',
                              error_color='#dc3545'), 400
    
    # 401错误处理
    @app.errorhandler(401)
    def unauthorized_error(error):
        # 如果是AJAX请求，返回JSON错误
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': '未授权访问',
                'login_required': True
            }), 401
        
        return render_template('errors/error.html', 
                              error_code=401,
                              error_title='未授权访问',
                              error_description='您需要登录才能访问此页面。',
                              error_icon='fa-lock',
                              error_color='#fd7e14'), 401
    
    # 429错误处理（请求过多）
    @app.errorhandler(429)
    def ratelimit_handler(error):
        # 如果是AJAX请求，返回JSON错误
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': '请求过于频繁，请稍后再试'
            }), 429
        
        return render_template('errors/error.html', 
                              error_code=429,
                              error_title='请求过于频繁',
                              error_description='您的请求过于频繁，请稍后再试。',
                              error_icon='fa-clock',
                              error_color='#fd7e14'), 429
    
    # 通用异常处理
    @app.errorhandler(Exception)
    def handle_exception(error):
        # 如果是HTTP异常，已经由上面的处理器处理
        if isinstance(error, HTTPException):
            return error
        
        # 记录错误信息
        error_id = str(uuid.uuid4())[:8]  # 生成简短的错误ID
        app.logger.error(f"Error ID: {error_id} - {str(error)}\n{traceback.format_exc()}")
        
        # 如果是AJAX请求，返回JSON错误
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return jsonify({
                'success': False,
                'message': '服务器内部错误',
                'error_id': error_id
            }), 500
        
        return render_template('errors/500.html', error_id=error_id), 500